package s.n.bespin.main;

import static s.n.bespin.enums.Args.CLASS_NAME;
import static s.n.bespin.enums.Args.METHOD_NAME;
import s.n.bespin.chain.ChainBuilder;
import s.n.bespin.chain.ChainBuilder.Chain;
import s.n.bespin.controller.CLIController;
import s.n.bespin.enums.Args;

/**
 * フレームワークBespinを起動するためのクラス。
 * 
 * @author NAGAI Satoshi
 */
public class Bespin {

	/**
	 * Bespinを起動します。
	 * 
	 * @param args
	 *            コマンドライン引数
	 */
	public static void main(final String[] args) {
		new Bespin().run(args);
	}

	/**
	 * Bespinを実行します。
	 * 
	 * @param args
	 *            コマンドライン引数
	 */
	public void run(final String[] args) {
		checkArguments(args);
		new CLIController().run(firstChain(args));
	}

	/**
	 * コマンドライン引数のチェックを行ないます。<br>
	 * チェック内容は下記。
	 * <ul>
	 * <li>{@code null}チェック</li>
	 * <li>要素数の不足チェック</li>
	 * </ul>
	 * 
	 * @param args
	 *            コマンドライン引数
	 * @throws NullPointerException
	 *             {@code args}が{@code null}の場合
	 * @throws IllegalArgumentException
	 *             {@code args}の要素数が不足している場合
	 */
	private void checkArguments(final String[] args)
			throws NullPointerException, IllegalArgumentException {
		if (args == null) {
			throw new NullPointerException(
					"The parameter [args] must not be null.");
		}
		if (args.length < Args.values().length) {
			throw new IllegalArgumentException(
					"The command line arguments must be "
							+ Args.values().length + " elements.");
		}
	}

	/**
	 * コマンドライン引数から初回チェインを生成して返します。
	 * 
	 * @param args
	 *            コマンドライン引数
	 * @return 初回チェイン
	 */
	private Chain firstChain(final String[] args) {
		return new ChainBuilder().className(args[CLASS_NAME.ordinal()])
				.methodName(args[METHOD_NAME.ordinal()]).call();
	}
}
